package com.czk.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.net.InetSocketAddress;
import java.util.Objects;

/**
 * netty的启动端
 *
 * @Author:ChenZhangKun
 * @Date: 2021/4/21 11:05
 */
@Component
public class NettyServer {
    /**
     * 创建日志
     */
    private static Logger LOGGER = LoggerFactory.getLogger(NettyServer.class);
    /**
     * 创建线程组
     */
    EventLoopGroup bossGroup = new NioEventLoopGroup(1);
    EventLoopGroup workGroup = new NioEventLoopGroup();
    /**
     * 通道
     */
    private Channel channel;
    @Autowired
    private MyChannelInitializer myChannelInitializer;

    public ChannelFuture bind(InetSocketAddress address) {
        ServerBootstrap bootstrap = new ServerBootstrap();
        ChannelFuture channelFuture = null;
        try {
            // 启动
            bootstrap
                    .group(bossGroup, workGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childHandler(myChannelInitializer);
            // 绑定
            channelFuture = bootstrap.bind(address).syncUninterruptibly();
            // 得到通道
            channel = channelFuture.channel();
        } catch (Exception ex) {
            LOGGER.error(ex.getMessage());
        } finally {
            if (!Objects.equals(null, channelFuture) && channelFuture.isSuccess()) {
                // 打印
                LOGGER.info("czk,成功了");
            } else {
                LOGGER.error("czk 失败了");
            }
        }
        return channelFuture;
    }

    /**
     * 关闭
     */
    public void destroy() {
        if (null == channel) return;
        channel.closeFuture();
        workGroup.shutdownGracefully();
        bossGroup.shutdownGracefully();
    }

    public Channel getChannel() {
        return channel;
    }
}
